// Author : Zhuowen Tu


#ifndef _MCMC_BLOCK_H
#define _MCMC_BLOCK_H

#include "mcPublic.h"
#include "mcmcLayerRegion.h"
#include "mcHeap.h"

class BoundCode
{
protected:
	double		y;
	bool		bShowOn;

public:
	// construction & destruction
	BoundCode();
	~BoundCode();

	// operators
	BoundCode&	operator=(const BoundCode &x);
	bool		operator==(const BoundCode &x);
	bool		operator<=(const BoundCode &x);
	bool		operator<(const BoundCode &x);
	friend bool	operator<(const BoundCode &x1, const BoundCode &x2);
	bool		operator>=(const BoundCode &x);
	bool		operator>(const BoundCode &x);

	// access
	inline void	Set(const double y1, const bool bS){y=y1;bShowOn=bS;};
	inline void	Get(double& y1, bool& bS){y1=y;bS=bShowOn;};
	inline double Y(void){return y;};
	inline bool	  show(void){return bShowOn;};
};

class MCMC_Boundary
{
public:
	MCMC_Boundary	*next;
	bool			*flag_pixel_on;
	McPoint2D		*points;
	int				num_points;
	irmm_Rect		rect_bound;

private:
	double			darea;

public:
	// construction & destruction
	MCMC_Boundary();
	~MCMC_Boundary();

	// operations
	void	SetPointCount(int size);
	void	Set(MCMC_AtomicRegion &region);
	void	Set(McPoint2D *p_points, const int num_points);

	void	Set(MCMC_Layer_Regions &graph, LinkList<int> &list_ver,LinkList<int> &list_cseg);
	void	Intersection(MinHeap<BoundCode> &heap, const McPoint2D &dp2d1, const McPoint2D &dp2d2);
	double	Area(void);
	double	GetArea(void){return darea;};
	bool	Inside(McPoint2D pt2d);
	bool	Clockwise(void);		//clockwise return true, counterclockwise return 0

private:
	void	Free(void);
};

class MCMC_Block
{
public:
	// construction & destruction
	MCMC_Block();
	~MCMC_Block();
	void Free(void);

	// operations
	void	Set(MCMC_AtomicRegion &region);
	int	Label(MCMC_AtomicRegion &region, mcmcMatrix<int> &image, const int id_label);
	void	LabelToPixelSet(MCMC_AtomicRegion &region, MCMC_PixelSet &pixel_set);
	void	LabelToList(LinkList<int> &list_rows, LinkList<int> &list_cols, McPoint2D *p_points, const int num_points,
						const int height, const int width);

private:
	void	EmptyHeap(void);

private:
	MCMC_Boundary		*pboundary_outer;
	MinHeap<BoundCode>	*pheap;
	irmm_Rect			rect_bound;
};

#define MI_GRID_SIZE 5

class MCMC_Grid_Index
{
public:
	LinkList<int>	pIndex_list[MI_GRID_SIZE*MI_GRID_SIZE];
	LinkList<int>	list_addtional;

protected:
	double			height,width;
	int				*pindex;

private:
	double			dh,dw;
	int				num_region;

public:
	// construction & destruction
	MCMC_Grid_Index();
	~MCMC_Grid_Index();

	void	Set(const double dheight, const double dwidth, const int num);
	int		Add(const irmm_Rect &rect, const int j);
	int		GetGridIndex(const int j);

protected:
	int		GetIndex(const double x, const double y);

};


#endif
